﻿namespace Beetle
{
    using System;
    using System.Runtime.InteropServices;

    public abstract class EofDataOfPackage : Package
    {
        private int _field_a;
        private bool _field_b;

        public EofDataOfPackage()
        {
            this._field_b = true;
        }

        public EofDataOfPackage(TcpChannel channel) : base(channel)
        {
            this._field_b = true;
        }

        public override void Import(byte[] data, int start, int count)
        {
            int num = start + count;
            while (count > 0)
            {
                if (this._field_b)
                {
                    base.Writer.Reset();
                    this._field_b = false;
                }
                if (this._field_a == 0)
                {
                    int num2 = Package.ByteIndexOf(data, this.EofData, start, count);
                    if (num2 == -1)
                    {
                        if ((base.Writer.Count + count) > TcpUtils.DataPacketMaxLength)
                        {
                            throw NetTcpException.DataOverflow();
                        }
                        base.Writer.Write(data, start, count);
                        int num3 = 0;
                        bool flag = false;
                        for (int j = num - (this.EofData.Length - 1); j < num; j++)
                        {
                            flag = true;
                            for (int k = 0; k < this.EofData.Length; k++)
                            {
                                if ((j + k) >= num)
                                {
                                    break;
                                }
                                if (data[j + k] != this.EofData[k])
                                {
                                    flag = false;
                                }
                            }
                            if (flag)
                            {
                                num3 = j;
                                break;
                            }
                        }
                        if (num3 == 0)
                        {
                            break;
                        }
                        this._field_a = num - num3;
                        return;
                    }
                    if ((base.Writer.Count + count) > TcpUtils.DataPacketMaxLength)
                    {
                        throw NetTcpException.DataOverflow();
                    }
                    base.Writer.Write(data, start, count);
                    start = num2 + 1;
                    count = num - start;
                    this.OnMessageDataReader(base.Writer);
                    this._field_a = 0;
                    this._field_b = true;
                    continue;
                }
                bool flag2 = true;
                int length = this.EofData.Length - this._field_a;
                for (int i = this._field_a; i < this.EofData.Length; i++)
                {
                    if (data[i - this._field_a] != this.EofData[i])
                    {
                        flag2 = false;
                    }
                }
                if (flag2)
                {
                    base.Writer.Write(data, start, length);
                    start += length;
                    count = num - start;
                    this.OnMessageDataReader(base.Writer);
                    this._field_b = true;
                }
                this._field_a = 0;
            }
        }

        public override IMessage MessageRead(BufferReader reader)
        {
            object obj2;
            IMessage message = this.ReadMessageByType(reader, out obj2);
            if (message == null)
            {
                throw NetTcpException.TypeNotFound(obj2.ToString());
            }
            try
            {
                message.Load(reader);
            }
            catch (Exception exception)
            {
                throw NetTcpException.ObjectLoadError(obj2.ToString(), exception);
            }
            return message;
        }

        public override void MessageWrite(IMessage msg, BufferWriter writer)
        {
            this.WriteMessageType(msg, writer);
            msg.Save(writer);
            writer.Write(this.EofData, 0, this.EofData.Length);
        }

        protected abstract IMessage ReadMessageByType(BufferReader reader, out object typeTag);
        protected abstract void WriteMessageType(IMessage msg, BufferWriter writer);

        protected abstract byte[] EofData { get; }
    }
}

